package com.tydic.borderer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tydic.borderer.domain.BorderAgent;
import com.tydic.borderer.domain.BordererInfo;
import com.tydic.borderer.domain.MutualHelpOrganization;
import com.tydic.borderer.domain.MutualHelpOrganizationMember;
import com.tydic.borderer.domain.bo.AddMutualHelpOrganizationMemberBo;
import com.tydic.borderer.domain.bo.MutualHelpOrganizationBo;
import com.tydic.borderer.domain.bo.QueryMutualHelpOrganizationBo;
import com.tydic.borderer.domain.vo.MutualHelpOrganizationMemberVo;
import com.tydic.borderer.domain.vo.MutualHelpOrganizationVo;
import com.tydic.borderer.mapper.BorderAgentMapper;
import com.tydic.borderer.mapper.BordererInfoMapper;
import com.tydic.borderer.mapper.MutualHelpOrganizationMapper;
import com.tydic.borderer.mapper.MutualHelpOrganizationMemberMapper;
import com.tydic.borderer.service.IBorderAgentService;
import com.tydic.borderer.service.IBordererInfoService;
import com.tydic.borderer.service.IMutualHelpOrganizationService;
import com.tydic.common.core.enums.AgentApplyStatusEnum;
import com.tydic.common.core.exception.api.ApiException;
import com.tydic.common.core.utils.StringUtils;
import com.tydic.common.mybatis.core.page.TableDataInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class MutualHelpOrganizationServiceImpl implements IMutualHelpOrganizationService {
    private final MutualHelpOrganizationMapper mutualHelpOrganizationMapper;
    private final MutualHelpOrganizationMemberMapper mutualHelpOrganizationMemberMapper;
    private final BordererInfoMapper bordererInfoMapper;
    private final IBordererInfoService bordererInfoService;
    private final IBorderAgentService borderAgentService;
    private final BorderAgentMapper borderAgentMapper;

    @Override
    public TableDataInfo<MutualHelpOrganizationVo> queryPage(QueryMutualHelpOrganizationBo bo) {
        IPage<MutualHelpOrganizationVo> page = mutualHelpOrganizationMapper.selectVoPage(bo.build(), buildQueryWrapper(bo));
        return TableDataInfo.build(page);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(MutualHelpOrganizationBo mutualHelpOrganizationRequest) {
        MutualHelpOrganization mutualHelpOrganization = BeanUtil.toBean(mutualHelpOrganizationRequest, MutualHelpOrganization.class);
        mutualHelpOrganizationMapper.insertOrUpdate(mutualHelpOrganization);
        mutualHelpOrganizationMemberMapper.delete(Wrappers.lambdaQuery(MutualHelpOrganizationMember.class).eq(MutualHelpOrganizationMember::getMutualHelpOrganizationId, mutualHelpOrganization.getId()));
        List<MutualHelpOrganizationMember> members = mutualHelpOrganizationRequest.getMembers().stream().map(item -> {
            MutualHelpOrganizationMember mutualHelpOrganizationMember = BeanUtil.toBean(item, MutualHelpOrganizationMember.class);
            mutualHelpOrganizationMember.setMutualHelpOrganizationId(mutualHelpOrganization.getId());
            return mutualHelpOrganizationMember;
        }).collect(Collectors.toList());
        mutualHelpOrganizationMemberMapper.insertBatch(members);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveMember(AddMutualHelpOrganizationMemberBo addMutualHelpOrganizationMemberRequest) {
        MutualHelpOrganizationMember mutualHelpOrganizationMember = BeanUtil.toBean(addMutualHelpOrganizationMemberRequest, MutualHelpOrganizationMember.class);
        mutualHelpOrganizationMemberMapper.insertOrUpdate(mutualHelpOrganizationMember);
    }

    @Override
    public Page<MutualHelpOrganization> page(QueryMutualHelpOrganizationBo queryMutualHelpOrganizationBo) {
        return mutualHelpOrganizationMapper.selectPage(queryMutualHelpOrganizationBo.build(), buildQueryWrapper(queryMutualHelpOrganizationBo));
    }

    @Override
    public List<MutualHelpOrganizationMember> getMembers(String id) {
        return mutualHelpOrganizationMemberMapper.selectList(Wrappers.lambdaQuery(MutualHelpOrganizationMember.class).eq(MutualHelpOrganizationMember::getMutualHelpOrganizationId, id));
    }

    @Override
    public MutualHelpOrganization get(String id) {
        return mutualHelpOrganizationMapper.selectById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        List<MutualHelpOrganizationMember> mutualHelpOrganizationMembers = mutualHelpOrganizationMemberMapper.selectList(Wrappers.lambdaQuery(MutualHelpOrganizationMember.class).eq(MutualHelpOrganizationMember::getMutualHelpOrganizationId, id));
        if (CollUtil.isNotEmpty(mutualHelpOrganizationMembers)) {
            mutualHelpOrganizationMembers.forEach(item -> {
                deleteMember(item.getId());
            });
        }
        mutualHelpOrganizationMapper.deleteById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteMember(String id) {
        MutualHelpOrganizationMember mutualHelpOrganizationMember = mutualHelpOrganizationMemberMapper.selectById(id);
        if (mutualHelpOrganizationMember == null) {
            throw new ApiException("该边民不存在");
        }
        BordererInfo bordererInfo = bordererInfoService.findByIdCardNumber(mutualHelpOrganizationMember.getIdCardNumber());
        if (bordererInfo != null) {
            // 删除互助组边民，把所有边民代表的关系作废
            List<BorderAgent> borderAgents = borderAgentService.findByBordererIdOrAgentBordererId(bordererInfo.getId(), bordererInfo.getId());
            if (CollUtil.isNotEmpty(borderAgents)) {
                for (BorderAgent borderAgent : borderAgents) {
                    borderAgent.setApplyStatus(AgentApplyStatusEnum.INVALID.getStatus());
                    borderAgentMapper.insertOrUpdate(borderAgent);
                }
            }
            // 删除互助组边民，更新边民对应的互助组信息为空
            bordererInfo.setBordererGroup("");
            bordererInfo.setBordererGroupRegisterNumber("");
            bordererInfoMapper.insertOrUpdate(bordererInfo);
        }
        mutualHelpOrganizationMemberMapper.deleteById(id);
    }

    @Override
    public MutualHelpOrganizationMember getMember(String id) {
        return mutualHelpOrganizationMemberMapper.selectById(id);
    }

    @Override
    public boolean existsByName(String name) {
        return mutualHelpOrganizationMapper.exists(Wrappers.lambdaQuery(MutualHelpOrganization.class).eq(MutualHelpOrganization::getName, name));
    }

    @Override
    public MutualHelpOrganizationMemberVo getByIdCardNumber(String idCardNumber) {
        MutualHelpOrganizationMember mutualHelpOrganizationMember = mutualHelpOrganizationMemberMapper.selectOne(Wrappers.lambdaQuery(MutualHelpOrganizationMember.class).eq(MutualHelpOrganizationMember::getIdCardNumber, idCardNumber), false);
        if (mutualHelpOrganizationMember == null) {
            throw new ApiException("未匹配该边民信息");
        }
        MutualHelpOrganization mutualHelpOrganization = mutualHelpOrganizationMapper.selectById(mutualHelpOrganizationMember.getMutualHelpOrganizationId());
        if (mutualHelpOrganization == null) {
            throw new ApiException("该边民对应的互助组不存在");
        }
        MutualHelpOrganizationMemberVo mutualHelpOrganizationMemberResponse = BeanUtil.toBean(mutualHelpOrganizationMember, MutualHelpOrganizationMemberVo.class);
        mutualHelpOrganizationMemberResponse.setMutualHelpOrganizationName(mutualHelpOrganization.getName());
        mutualHelpOrganizationMemberResponse.setMutualHelpOrganizationRegisterNumber(mutualHelpOrganization.getRegisterNumber());
        mutualHelpOrganizationMemberResponse.setPhoneNumber(mutualHelpOrganizationMember.getMobile());
        return mutualHelpOrganizationMemberResponse;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(MutualHelpOrganization mutualHelpOrganization, List<MutualHelpOrganizationMember> mutualHelpOrganizationMembers) {
        mutualHelpOrganizationMapper.insertOrUpdate(mutualHelpOrganization);
        if (CollUtil.isEmpty(mutualHelpOrganizationMembers)) {
            return;
        }
        for (MutualHelpOrganizationMember mutualHelpOrganizationMember : mutualHelpOrganizationMembers) {
            mutualHelpOrganizationMember.setMutualHelpOrganizationId(mutualHelpOrganization.getId());
            mutualHelpOrganizationMemberMapper.insertOrUpdate(mutualHelpOrganizationMember);
            updateBordererInfo(mutualHelpOrganization, mutualHelpOrganizationMember);
        }
    }

    private void updateBordererInfo(MutualHelpOrganization mutualHelpOrganization, MutualHelpOrganizationMember mutualHelpOrganizationMember) {
        BordererInfo bordererInfo = bordererInfoService.findByIdCardNumber(mutualHelpOrganizationMember.getIdCardNumber());
        if (bordererInfo != null) {
            bordererInfo.setBordererGroup(mutualHelpOrganization.getName());
            bordererInfo.setBordererGroupRegisterNumber(mutualHelpOrganization.getRegisterNumber());
            bordererInfoMapper.insertOrUpdate(bordererInfo);
        }
    }


    private LambdaQueryWrapper<MutualHelpOrganization> buildQueryWrapper(QueryMutualHelpOrganizationBo bo) {
        LambdaQueryWrapper<MutualHelpOrganization> lqw = Wrappers.lambdaQuery(MutualHelpOrganization.class);
        lqw.like(StringUtils.isNotBlank(bo.getName()), MutualHelpOrganization::getName, bo.getName());
        lqw.like(StringUtils.isNotBlank(bo.getPrincipal()), MutualHelpOrganization::getPrincipal, bo.getPrincipal());
        lqw.orderByDesc(MutualHelpOrganization::getCreateDate);
        return lqw;
    }
}
